home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 16
/
Aminet 16 (1996)(GTI - Schatztruhe)[!][Dec 1996].iso
/
Aminet
/
misc
/
emu
/
QDOS2.lha
/
QLsource
/
ROMsrc
/
SYS
/
MOVEP_ASM
< prev
next >
Wrap
Text File
|
1995-08-27
|
6KB
|
308 lines
; INPUT *************************************************************** #
; none #
; #
; OUTPUT ************************************************************** #
; If exiting through isp_dacc... #
; a0 = failing address #
; d0 = FSLW #
; else #
; none #
; #
; ALGORITHM *********************************************************** #
; Decode the movep instruction words stored at EXC_OPWORD and #
; either read or write the required bytes from/to memory. Use the #
; _dmem_{read,write}_byte() routines. If one of the memory routines #
; returns a failing value, we must pass the failing address and a FSLW #
; to the _isp_dacc() routine. #
; Since this instruction is used to access peripherals, make sure #
; to only access the required bytes. #
; XDEF _moveperipheral ; emulate movep instruction
; XREF _dmem_read_byte ; read byte from memory
; XREF _dmem_write_byte ; write byte to memory
; XREF _isp_dacc ; handle data access error exception
; ###########################
; movep.(w,l) Dx,(d,Ay) #
; movep.(w,l) (d,Ay),Dx #
; ###########################
EXC_AREGS equ 4+$20
EXC_DREGS equ 4+$0
EXC_PC equ 4+$42
EXC_OPWORD equ $0
EXC_EXTWORD equ $2
_moveperipheral:
move.l EXC_PC(a7),a6
move.w EXC_OPWORD(a6),d1 ; fetch the opcode word
move.b d1,d0
and.w #$7,d0 ; extract Ay from opcode word
dc.w $2077,$0404 ; move.l (EXC_AREGS,a7,d0.w*4),a0 ; fetch ay
; lsl.w #2,d0
; move.l EXC_AREGS(a7,d0.w),a0
; lsr.w #2,d0
add.w EXC_EXTWORD(a6),a0 ; add: an + sgn_ext(disp)
btst #$7,d1 ; (reg 2 mem) or (mem 2 reg)
beq.w mem2reg
; reg2mem: fetch dx, then write it to memory
reg2mem:
move.w d1,d0
rol.w #$7,d0
and.w #$7,d0 ; extract Dx from opcode word
dc.w $2037,$0424 ; move.l (EXC_DREGS,a7,d0.w*4),d0 ; fetch dx
; lsl.w #2,d0
; move.l EXC_DREGS(a7,d0.w),d0
; lsr.w #2,d0
btst #$6,d1 ; word or long operation?
beq.b r2mwtrans
; a0 = dst addr
; d0 = Dx
r2mltrans:
move.l d0,d2 ; store data
move.l a0,a2 ; store addr
rol.l #$8,d2
move.l d2,d0
bsr.l _dmem_write_byte ; os : write hi
tst.l d1 ; dfetch error?
bne.w movp_write_err ; yes
add.w #$2,a2 ; incr addr
move.l a2,a0
rol.l #$8,d2
move.l d2,d0
bsr.l _dmem_write_byte ; os : write lo
tst.l d1 ; dfetch error?
bne.w movp_write_err ; yes
add.w #$2,a2 ; incr addr
move.l a2,a0
rol.l #$8,d2
move.l d2,d0
bsr.l _dmem_write_byte ; os : write lo
tst.l d1 ; dfetch error?
bne.w movp_write_err ; yes
add.w #$2,a2 ; incr addr
move.l a2,a0
rol.l #$8,d2
move.l d2,d0
bsr.l _dmem_write_byte ; os : write lo
tst.l d1 ; dfetch error?
bne.w movp_write_err ; yes
bra _movep_exit ; (rts)
; a0 = dst addr
; d0 = Dx
r2mwtrans:
move.l d0,d2 ; store data
move.l a0,a2 ; store addr
lsr.w #$8,d0
bsr.l _dmem_write_byte ; os : write hi
tst.l d1 ; dfetch error?
bne.w movp_write_err ; yes
add.w #$2,a2
move.l a2,a0
move.l d2,d0
bsr.l _dmem_write_byte ; os : write lo
tst.l d1 ; dfetch error?
bne.w movp_write_err ; yes
bra _movep_exit ; (rts)
; mem2reg: read bytes from memory.
; determines the dest register, and then writes the bytes into it.
mem2reg:
btst #$6,d1 ; word or long operation?
beq.b m2rwtrans
; a0 = dst addr
m2rltrans:
move.l a0,a2 ; store addr
bsr.l _dmem_read_byte ; read first byte
tst.l d1 ; dfetch error?
bne.w movp_read_err ; yes
move.l d0,d2
add.w #$2,a2 ; incr addr by 2 bytes
move.l a2,a0
bsr.l _dmem_read_byte ; read second byte
tst.l d1 ; dfetch error?
bne.w movp_read_err ; yes
lsl.w #$8,d2
move.b d0,d2 ; append bytes
add.w #$2,a2 ; incr addr by 2 bytes
move.l a2,a0
bsr.l _dmem_read_byte ; read second byte
tst.l d1 ; dfetch error?
bne.w movp_read_err ; yes
lsl.l #$8,d2
move.b d0,d2 ; append bytes
add.w #$2,a2 ; incr addr by 2 bytes
move.l a2,a0
bsr.l _dmem_read_byte ; read second byte
tst.l d1 ; dfetch error?
bne.w movp_read_err ; yes
lsl.l #$8,d2
move.b d0,d2 ; append bytes
move.b EXC_OPWORD(a6),d1
lsr.b #$1,d1
and.w #$7,d1 ; extract Dx from opcode word
dc.w $2F82,$1424 ; move.l d2,(EXC_DREGS,a7,d1.w*4) ; store dx
; lsl.w #2,d1
; move.l d2,EXC_DREGS(a7,d1.w)
; lsr.w #2,d1
bra _movep_exit ; (rts)
; a0 = dst addr
m2rwtrans:
move.l a0,a2 ; store addr
bsr.l _dmem_read_byte ; read first byte
tst.l d1 ; dfetch error?
bne.w movp_read_err ; yes
move.l d0,d2
add.w #$2,a2 ; incr addr by 2 bytes
move.l a2,a0
bsr.l _dmem_read_byte ; read second byte
tst.l d1 ; dfetch error?
bne.w movp_read_err ; yes
lsl.w #$8,d2
move.b d0,d2 ; append bytes
move.b EXC_OPWORD(a6),d1
lsr.b #$1,d1
and.w #$7,d1 ; extract Dx from opcode word
dc.w $2F82,$1426 ; move.w d2,(EXC_DREGS+2,a7,d1.w*4) ; store dx
; lsl.w #2,d1
; move.w d2,EXC_DREGS+2(a7,d1.w)
; lsr.w #2,d1
bra _movep_exit ; (rts)
; if dmem_{read,write}_byte() returns a fail message in d1, the package
; must create an access error frame. here, we pass a skeleton fslw
; and the failing address to the routine that creates the new frame.
; FSLW:
; write = true
; size = byte
; TM = data
; software emulation error = true
movp_write_err:
move.l a2,a0 ; pass failing address
move.l #$00a10001,d0 ; pass fslw
bra.l _isp_dacc
; FSLW:
; read = true
; size = byte
; TM = data
; software emulation error = true
movp_read_err:
move.l a2,a0 ; pass failing address
move.l #$01210001,d0 ; pass fslw
bra.l _isp_dacc
_dmem_read_byte:
movem.l a1-a4,-(a7)
move.l a7,a4 ; save for later
dc.w $4E7A,$B801 ; movec vbr,a3
; sub.l a3,a3
move.l $08(a3),a1 ; (bus err vector)
lea _dmem_read_EXIT(pc),a2
move.l a2,$08(a3)
moveq #-1,d1
move.b (a0),d0 ; read byte
moveq #0,d1
_dmem_read_EXIT:
move.l a1,$08(a3) ; (bus err vector)
move.l a4,a7 ; tidy up stack
movem.l (a7)+,a1-a4
rts
_dmem_write_byte:
movem.l a1-a4,-(a7)
move.l a7,a4 ; save for later
dc.w $4E7A,$B801 ; movec vbr,a3
; sub.l a3,a3
move.l $08(a3),a1 ; (bus err vector)
lea _dmem_write_EXIT(pc),a2
move.l a2,$08(a3)
moveq #-1,d1
move.b d0,(a0) ; write byte
moveq #0,d1
_dmem_write_EXIT:
move.l a1,$08(a3) ; (bus err vector)
move.l a4,a7 ; tidy up stack
movem.l (a7)+,a1-a4
rts
_isp_dacc: ; just ignore
_movep_exit:
addq.l #4,EXC_PC(a7)
rts